package com.mach.platform.sprider.dev.virdev;

import com.mach.platform.sprider.dev.ByteUtil;
import com.mach.platform.sprider.dev.UU;
import com.mach.platform.sprider.getter.GeneralModbusDev;
import com.mach.platform.sprider.getter.MainWork;
import com.mach.platform.sprider.getter.DataLogService;
import com.mach.platform.util.SqlHelper;
import com.mach.platform.util.U;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Slf4j
public class TransducerCtrDev extends GeneralModbusDev implements VirDev {



    private SqlHelper sqlHelper;
    private  DataLogService dataLogService;
    private  Map<String, Object> devInfoMap;
    private  Integer devId;
    private boolean isRun = false;
    private int frep = 0;
    private Integer cmdCode = 3;


    private TransducerCtrDev(Map<String, Object> devInfoMap, SqlHelper sqlHelper, DataLogService dataLogService) throws SQLException {
        super(devInfoMap, sqlHelper, dataLogService);

        this.devInfoMap = devInfoMap;

        this.sqlHelper = sqlHelper;

        this.dataLogService = dataLogService;
    }
    private static HashMap<Integer, TransducerCtrDev> tcvMap = new HashMap<Integer, TransducerCtrDev>(4);
    public static TransducerCtrDev getAndNew(Map<String, Object> devInfoMap, SqlHelper sqlHelper, DataLogService dataLogService) throws SQLException {
        TransducerCtrDev rs = null;
        Integer devId = (Integer)devInfoMap.get("devId");
        rs = tcvMap.get(devId);
        if(rs == null){
            rs = new TransducerCtrDev(devInfoMap,  sqlHelper,  dataLogService);
            tcvMap.put(devId, rs);
        }
        return rs;
    }

    @Override
    protected void pick() {
//        "select dev.id devId, dev.name name,type.prol prol,  dev.dev_type_id devTypeId,\n" +
//                " coll.id collId, coll.name collName, coll.value_addr collAddr,\n " +
//                " dev.comm_addr commAddr,\n" +
//                " coll.data_len collLen, coll.data_type collDataType,\n"；

        Map<Integer, Object> collMap = (Map<Integer, Object>) this.devInfoMap.get("coll");

        Set<Map.Entry<Integer, Object>> collEntrys = collMap.entrySet();

        for(Map.Entry<Integer, Object> collEntry : collEntrys){
            Map<String, Object> coll = (Map<String, Object>) collEntry.getValue();

            Integer devId = (Integer)this.devInfoMap.get("devId");
            String collName = (String)coll.get("collName");
            BigDecimal collAddr = (BigDecimal)coll.get("collAddr");
            Integer collLen = (Integer)coll.get("collLen");
            String collDataType = (String)coll.get("collDataType");
            String collUnit = (String)coll.get("collUnit");
            String prol = (String)this.devInfoMap.get("prol");
            this.cmdCode = (Integer)coll.get("collFunCode");
            if(cmdCode == null) cmdCode = 3;
            Object result = null;

//            log.info("collName"+ collName);

            try {
                byte[] databuf = null;
                if("TransducerCtrDevGeneralModbusRTU".equals(prol)){
                    byte[] orgData = this.dh.getDataRtu(collAddr.intValue(), 2,cmdCode);
                   if(orgData == null || orgData.length <1)continue;
                    databuf = ByteUtil.subData(orgData,3,collLen.intValue());
                }else
                if ("TransducerCtrDevGeneralModbusRTU".equals(prol)){
                    byte[] orgData = this.dh.getDataTcp(collAddr.intValue(), 2,cmdCode);
                   if(orgData == null || orgData.length <1)continue;
                    databuf = ByteUtil.subData(orgData,9,collLen.intValue());
                }

                databuf = ByteUtil.reverse(databuf);
                Short resultInt = ByteUtil.getShort(databuf);
                result = resultInt;

                if( "运行状态".equals(collName) ){
                    result = resultInt;
                }

                if( "输出频率".equals(collName) ){
                    result = resultInt;
                }

            }catch (Exception e){
                e.printStackTrace();
                System.err.println("error msg:" + e.getLocalizedMessage() + " devId=" + this.devId + "");
                result = null;
            }

            if(result != null){
                try {
//                    sqlHelper.updateAsync(
//                            "replace into iot_dev_cur_data_win" +
//                                    "(dev_id, data_type,dvalue,unit,uptime)" +
//                                    " value("+devId+", '"+collName+"', "+result+",'"+collUnit+"',now())");

                    MainWork.addResultJustCur(devInfoMap, coll,result);
//                    sqlHelper.updateAsync(
//                            "insert into iot_dev_data_win" +
//                                    "(order_num,dev_id, the_time,data_type,dvalue)" +
//                                    " value(1,"+devId+",now(), '"+collName+"', "+result+")");

                    //this.dataLogService.addDataLogAsync(devId, new Date(), collName, result);

                } catch (Exception e) {
                    e.printStackTrace();
                    System.err.println("error saveToDb... msg:" + e.getLocalizedMessage() + " devId=" + this.devId + "");
                }
            }

        }

    }

    @Override
    public void cmd(Integer cmdLogId,String cmd, String param) {

        try {
            Integer devTypeId = (Integer)this.devInfoMap.get("devTypeId");

            Map<Object, Object> addrMap = sqlHelper.getMapFrTable("name", "valueAddr",
                    "select name, value_addr valueAddr " +
                            " from iot_coll_items colls " +
                            " where colls.dev_type_id=" + devTypeId);

            BigDecimal cmdAddr = (BigDecimal)addrMap.get("控制指令");
            BigDecimal etaAddr = (BigDecimal)addrMap.get("状态字");
            BigDecimal setFrepAddr = (BigDecimal)addrMap.get("给定频率");
            BigDecimal setReset = (BigDecimal)addrMap.get("复位值");
            BigDecimal setStop = (BigDecimal)addrMap.get("停车");
            BigDecimal setRun = (BigDecimal)addrMap.get("启动");
            BigDecimal setOk = (BigDecimal)addrMap.get("允许运行");
            BigDecimal setNst = (BigDecimal)addrMap.get("自由停车");

            if(setFrepAddr != null
                    && etaAddr != null
                    && setReset != null
                    && setStop != null
                    && etaAddr != null
                    && setOk != null
                    && setNst != null
                    && cmdAddr != null ){

                if("setFrep".equals(cmd)){
                    this.frep = Integer.parseInt(param);

                    //this.dh.setDataRtu(ctrAddr, 1);
                    if(!this.isRun){
                        this.dh.setDataRtu(cmdAddr.intValue(), setReset.intValue());//复位
                        UU.sleep(1000*1);
                        Short etaStatus = this.dh.getShortData(etaAddr.intValue(), cmdCode);
                        etaStatus = this.dh.getShortData(etaAddr.intValue(), cmdCode);
                        if((etaStatus & 0x50 ) > 0 ){
                            this.dh.setDataRtu(cmdAddr.intValue(), setStop.intValue());//
                            UU.sleep(1000*3);
                        }
                        etaStatus = this.dh.getShortData(etaAddr.intValue(), cmdCode);
                        if((etaStatus & 0x31 ) > 0 ){
                            this.dh.setDataRtu(cmdAddr.intValue(), setRun.intValue());//
                            UU.sleep(1000*3);
                        }
                        etaStatus = this.dh.getShortData(etaAddr.intValue(), cmdCode);
                        etaStatus = this.dh.getShortData(etaAddr.intValue(), cmdCode);
                        if((etaStatus & 0x33 ) > 0  && !this.isRun){

                            U.cachedThreadPool.execute(new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        TransducerCtrDev.this.isRun = true;
                                        while(TransducerCtrDev.this.isRun){
                                            Double outFrep = (Double) TransducerCtrDev.this.getValueByCollName("输出频率");

                                            if(outFrep < 30){
                                                TransducerCtrDev.this.isRun = false;
                                                break;
                                            }

                                            TransducerCtrDev.this.dh.setDataRtu(setFrepAddr.intValue(), frep);//设频
                                            TransducerCtrDev.this.dh.setDataRtu(cmdAddr.intValue(), setOk.intValue());//
                                            UU.sleep(500);
                                        }
                                    }catch (Exception e){
                                        e.printStackTrace();
                                    }
                                    finally {
                                        TransducerCtrDev.this.isRun = false;
                                    }
                                }
                            });
                        }
                        if((etaStatus & 0x80 ) > 0 ){
                            throw new StartFailException("故障");
                        }
                    }else{

                    }



//                    this.dh.setDataRtu(cmdAddr, setReset);//复位
//                    this.dh.setDataRtu(cmdAddr, setStop);//停车
//                    this.dh.setDataRtu(cmdAddr, setRun);//启动
//                    this.dh.setDataRtu(cmdAddr, setOk);//ok

                }//setFrep

                if("stop".equals(cmd)){
//                    this.dh.setDataRtu(cmdAddr.intValue(), setNst.intValue());//自由停车
                    this.isRun = false;
                    this.frep = 0;
                }

                sqlHelper.update(
                        "update iot_dev_cmd_log set resp_code=1,resp_ctx='"+EXE_SUCS_CTX+"' where id=" + cmdLogId);

            }else{
                sqlHelper.update(
                        "update iot_dev_cmd_log set resp_code=2,resp_ctx='非远程状态无法控制.' where id=" + cmdLogId);
            }

        } catch (Exception e) {
            e.printStackTrace();
            sqlHelper.updateAsync(
                    "update iot_dev_cmd_log set resp_code=0,resp_ctx='"+e.getLocalizedMessage()+"' where id=" + cmdLogId);
        }finally {
            sqlHelper.updateAsync(
                    "update iot_dev_cmd_log set resp_time=now() where id=" + cmdLogId);
        }




        return;
    }

//    @Override
//    public Object getValueByCollName(String collName) throws IOException {
//        Object result = null;
//
//        if(collName == null)return null;
//
//        if("".equals(collName)){
//
//        }
//
//        Map<String, Object> coll = this.getCollByName(collName);
//
//        if(coll == null)return null;
//
//        result = this.getValueByColl(coll);
//
//        return result;
//    }

   public int getFrep(){
        return this.frep;
   }

    public boolean isRun() {
        return isRun;
    }
}
